package com.tan.lighting.disruptor.adapter;


import com.lmax.disruptor.dsl.Disruptor;
import com.tan.lighting.concurrent.DeferredResult;
import com.tan.lighting.ddd.CommonCommand;
import com.tan.lighting.disruptor.event.CommandEvent;

import java.util.concurrent.Callable;

public abstract class DisruptorCmdServiceBase {
    protected <T> T publishEvent(Disruptor<CommandEvent> disruptor, CommonCommand cmd, Callable<T> callable) {
        DeferredResult<T> deferredResult = new DeferredResult<>();
        disruptor.publishEvent((event, sequence) -> {
            event.setCmd(cmd);
            event.setHandler(() -> {
                T returnObj = null;
                try {
                    returnObj = callable.call();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                deferredResult.setResult(returnObj);
                return null;
            });

        });
        T result = getResult(deferredResult);
        return result;
    }

    private <T> T getResult(DeferredResult<T> deferredResult) {
        try {
            return deferredResult.getResult();
        } catch (InterruptedException e) {
            e.printStackTrace();
            return null;
        }
    }
}
